﻿#define _CRT_SECURE_NO_WARNINGS 1
// 原题连接：https://www.nowcoder.com/practice/6a7b2b6c9e3a4f56b1db9f8ca08d889b?tpId=230&tqId=38958&ru=/exam/oj

/*
题目描述：
小红拿到了一个数组，她想取一些数使得取的数之和尽可能大，但要求这个和必须是
k

k  的倍数。
你能帮帮她吗？
输入描述：
第一行输入两个正整数
n

n  和
k

k
第二行输入
n

n  个正整数
a
i

a
i
​

1
≤
n
,
k
≤
1
0
3
1≤n,k≤10
3

1
≤
a
i
≤
1
0
10
1≤a
i
​
 ≤10
10

输出描述：
如果没有合法方案，输出 -1。
否则输出最大的和。
示例1
输入：
5 5
4 8 2 9 1
复制
输出：
20
复制
说明：
取后四个数即可
*/

// 开始解题：
// 方法——动态规划(01背包 + 同余原理)
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010;
const int INF = 0x3f3f3f3f;
int n = 0, k = 0;
long long nums[N];
long long dp[N][N]; // dp[i][j]表示从前i个树中选出的最大总和，并且总模k等于j

int main() {
    memset(dp, -INF, sizeof dp);
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &nums[i]);
    }
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < k; j++) {
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][((j - nums[i] % k) + k) % k] + nums[i]);
        }
    }
    if (dp[n][0] <= 0) {
        printf("-1\n");
    }
    else {
        printf("%lld\n", dp[n][0]);
    }
    return 0;
}